package com.powerunion.datacollection.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.powerunion.datacollection.common.Constants;
import com.powerunion.datacollection.dao.ActivityDao;
import com.powerunion.datacollection.dao.DaoException;
import com.powerunion.datacollection.model.ActivityInfo;
import com.powerunion.datacollection.model.ActivityInstance;
import com.powerunion.datacollection.model.ApproveActivityInstance;
import com.powerunion.datacollection.persistence.db.jdbc.operator.QueryOperator;
import com.powerunion.datacollection.persistence.db.jdbc.operator.RsDataSet;
import com.powerunion.datacollection.persistence.db.jdbc.operator.SqlParameter;
import com.powerunion.datacollection.persistence.db.jdbc.operator.SqlType;
import com.powerunion.datacollection.persistence.db.jdbc.operator.UpdateOperator;
import com.powerunion.util.DBUtils;
import com.powerunion.util.log.LogHelper;

public class ActivityDaoImpl extends JdbcBase implements ActivityDao {
	// 初始化日志类
	private static final Logger logger = LogHelper.getInstance().getLogger(
			ActivityDaoImpl.class);

	public ApproveActivityInstance getParentActivity(String childId)
			throws DaoException {

		StringBuffer sql = new StringBuffer();
		sql
				.append(
						"select id,item_id,act_type,filltype_or_apptype,act_name,")
				.append(
						"time_limit,approle_or_urgdate,examrol_or_colrol,description,")
				.append(
						"act_state,iupdata,urgency_content from dc_proc_instance where id=(select para_id ")
				.append(" from dc_proc_instance where id=?)");

		QueryOperator query = new QueryOperator();
		query.setSql(sql.toString());
		query.addParameter(new SqlParameter(SqlType.VARCHAR, childId));
		ApproveActivityInstance aai = null;
		try {
			query.access();
			aai = new ApproveActivityInstance();
			if (query.resultSetAvailable()) {
				// 获取并处理记录集
				RsDataSet rs = new RsDataSet(query.getSqlResultSet());

				if (rs.rowCount > 0) {
					int i = 0;
					aai.setActivityId(rs.getFieldValueAsString(i++));
					aai.setProcId(rs.getFieldValueAsString(i++));
					Integer type = rs.getFieldValueAsInteger(i++);
					int typeInt = type == null ? 0 : type.intValue();
					aai.setActivityType(typeInt);

					Integer foType = rs.getFieldValueAsInteger(i++);
					int foTypeInt = foType == null ? 0 : foType.intValue();
					aai.setFillTypeOrapproveType(foTypeInt);
					aai.setActivityName(rs.getFieldValueAsString(i++));
					aai.setTimeLimit(rs.getFieldValueAsString(i++));
					aai.setApproveUserOrurgencyDate(rs
							.getFieldValueAsString(i++));
					aai.setExamineUserOrcollectionUser(rs
							.getFieldValueAsString(i++));
					aai.setDescription(rs.getFieldValueAsString(i++));

					Integer a = rs.getFieldValueAsInteger(i++);
					int aInt = a == null ? 0 : a.intValue();
					aai.setActState(aInt);
					aai.setIupdata(rs.getFieldValueAsInteger(i++).intValue());
					aai.setUrgencyContent(rs
							.getFieldValueAsString("urgency_content"));
					// aai.setRepeatCount(rs.getFieldValueAsInteger("repeat_count").intValue());
					// aai.setRepeatIntervalDay(rs.getFieldValueAsInteger("repeat_interval_day").intValue());
					// aai.setRepeatIntervalHour(rs.getFieldValueAsInteger("repeat_interval_hour").intValue());

					aai.setSubmiUser(childId);
				}

				rs.clearAll();
			}

		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("查找编码为：" + childId + "的上级审批任务失败！");
		}
		return aai;

	}

	/**
	 * 更新状态
	 * 
	 * @param state
	 * @param id
	 * @return
	 */
	public boolean updateActivityState(int state, String id)
			throws DaoException {
		String sql = "update dc_proc_instance set act_state=? where id = ?";
		UpdateOperator update = new UpdateOperator();
		update.setSql(sql);
		update.addParameter(new SqlParameter(SqlType.INTEGER,
				new Integer(state)));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, id));

		try {
			update.access();
		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("更新id为：" + id + " 的环节状态失败！");
		}

		int effectCount = update.getEffectCounts();
		if (effectCount > 0) {
			if (logger.isDebugEnabled()) {
				logger.debug("updateActivityState:" + Constants.UPDATE + "环节状态"
						+ Constants.SUCCESS);
			}
			return true;
		} else {
			if (logger.isDebugEnabled()) {
				logger.debug("updateActivityState:" + Constants.UPDATE + "环节状态"
						+ Constants.FAIL);
			}
			return false;
		}
	}

	public boolean updateActivityState4Child(int state, String id)
			throws DaoException {
		String sql = "update dc_proc_instance set act_state=? where para_id = ? and act_state <> 5 ";
		UpdateOperator update = new UpdateOperator();
		update.setSql(sql);
		update.addParameter(new SqlParameter(SqlType.INTEGER,
				new Integer(state)));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, id));

		try {
			update.access();
		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("更新父id为：" + id + " 的所有环节状态失败！");
		}

		int effectCount = update.getEffectCounts();
		if (effectCount > 0) {
			if (logger.isDebugEnabled()) {
				logger.debug("updateActivityState4Child:" + Constants.UPDATE
						+ "环节状态" + Constants.SUCCESS);
			}
			return true;
		} else {
			if (logger.isDebugEnabled()) {
				logger.debug("updateActivityState4Child:" + Constants.UPDATE
						+ "环节状态" + Constants.FAIL);
			}
			return false;
		}
	}

	/**
	 * 根据流程定义ID查找所有环节信息
	 * 
	 * @param processId
	 *            流程ID
	 * @return
	 */
	public List findAllActivityByProcId(String processId) throws DaoException {
		Connection conn = null;

		StringBuffer sql = new StringBuffer();
		// sql.append("select
		// id,para_id,activity_type,filltype_or_approvetype,activity_name,")
		// .append("time_limit,approveuser_or_urgencydate,examineuser_or_collectionuser,")
		// .append("description,exa_Or_col_type,iupdata,urgency_content from
		// dc_process_table where item_id = ? and para_id=?");
		sql
				.append(
						"select d.id,d.item_id,d.para_id,d.activity_type,d.activity_name,d.time_limit,d.approveUser_Or_urgencyDate,d.fillType_Or_approveType,")
				.append(
						"d.examineUser_Or_collectionUser,d.description,d.exa_Or_col_type,d.iupdata,d.urgency_content,u.urge_time,u.urge_info,u.remind_info,  ")
				.append(
						" u.repeat_count,u.repeat_interval_day,u.repeat_interval_hour from dc_process_table d left join ")
				.append(
						" dc_urgency u on d.id=u.act_id  where d.item_id=? and d.para_id=? ");

		List activityList = null;
		try {
			conn = this.getConnection();
			activityList = new ArrayList();
			activityList = this.getActivity(conn, processId, "null", sql
					.toString());
		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("查找流程Id为：" + processId + " 的所有环节信息出错！");
		} finally {
			DBUtils.close(conn);
		}
		return activityList;
	}

	private List getActivity(Connection conn, String processId, String paraId,
			String sql) throws DaoException {
		logger.info(Constants.INTOMETHOD + "getActivity");
		PreparedStatement ps = null;
		ResultSet rs = null;
		List activityArray = null;

		try {
			ps = conn.prepareStatement(sql);
			ps.setString(1, processId);
			ps.setString(2, paraId);
			rs = ps.executeQuery();
			activityArray = new ArrayList();

			while (rs.next()) {
				ActivityInfo ai = new ActivityInfo();
				ai.setParaId(rs.getString("para_id"));
				ai.setActivityId(rs.getString("id"));
				ai.setActivityType(rs.getInt("activity_type"));
				ai.setFillTypeOrapproveType(rs
						.getInt("filltype_or_approvetype"));
				ai.setActivityName(rs.getString("activity_name"));
				ai.setTimeLimit(rs.getString("time_limit"));
				ai.setApproveUserOrurgencyDate(rs
						.getString("approveuser_or_urgencydate"));
				ai.setExamineUserOrcollectionUser(rs
						.getString("examineuser_or_collectionuser"));
				ai.setDescription(rs.getString("description"));
				ai.setExamineUserOrcollectionUserTypes(rs
						.getString("exa_Or_col_type"));
				ai.setIupdata(rs.getInt("iupdata"));
				ai.setUrgencyContent(rs.getString("urge_info"));
				ai.setRemindContent(rs.getString("remind_info"));
				ai.setUrgencyDate(rs.getString("urge_time"));
				ai.setRepeatCount(rs.getInt("repeat_count"));
				ai.setRepeatIntervalDay(rs.getInt("repeat_interval_day"));
				ai.setRepeatIntervalHour(rs.getInt("repeat_interval_hour"));

				List data = new ArrayList();

				// 递归调用
				data = this.getActivity(conn, processId, ai.getActivityId(),
						sql);
				if (!data.isEmpty()) {
					ai.setData(data);
				}
				activityArray.add(ai);
			}

			logger.debug(Constants.SEARCH + "环节信息" + Constants.SUCCESS);

		} catch (Exception e) {
			logger.error("getActivity() of throws : ", e);
			throw new DaoException(Constants.SEARCH + "环节信息" + Constants.FAIL);
		} finally {
			DBUtils.close(rs, ps);
		}
		return activityArray;
	}

	public ActivityInstance getActivityInfoByKey(String id) throws DaoException {
		StringBuffer sql = new StringBuffer();

		sql
				.append(
						"select p.id,p.proc_id,p.para_id,p.item_id,p.act_type,p.fillType_Or_appType,p.act_name,")
				.append(
						"p.time_limit,p.appRole_Or_urgDate,p.examRol_Or_colRol,p.description,p.act_state,p.exa_Or_col_type,")
				.append(
						"p.iupdata,u.urge_time,u.urge_info,u.remind_info,u.repeat_count,u.repeat_interval_day,u.repeat_interval_hour ")
				.append(
						" from dc_proc_instance p left join dc_urgency u on p.id=u.act_id where p.id = ?");
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		ActivityInstance ai = new ActivityInstance();
		try {
			conn = this.getConnection();
			ps = conn.prepareStatement(sql.toString());
			ps.setString(1, id);
			rs = ps.executeQuery();
			if (rs.next()) {
				ai.setParaId(rs.getString("para_id"));
				ai.setActivityId(rs.getString("id"));
				ai.setProcId(rs.getString("proc_id"));
				ai.setActivityType(rs.getInt("act_type"));
				ai.setFillTypeOrapproveType(rs.getInt("fillType_Or_appType"));
				ai.setActivityName(rs.getString("act_name"));
				ai.setTimeLimit(rs.getString("time_limit"));
				ai.setApproveUserOrurgencyDate(rs
						.getString("appRole_Or_urgDate"));
				ai.setExamineUserOrcollectionUser(rs
						.getString("examRol_Or_colRol"));
				ai.setDescription(rs.getString("description"));
				ai.setActState(rs.getInt("act_state"));
				ai.setExamineUserOrcollectionUserTypes(rs
						.getString("exa_Or_col_type"));
				ai.setIupdata(rs.getInt("iupdata"));
				ai.setUrgencyContent(rs.getString("urge_info"));
				ai.setRemindContent(rs.getString("remind_info"));
				ai.setUrgencyDate(rs.getString("urge_time"));
				ai.setRepeatCount(rs.getInt("repeat_count"));
				ai.setRepeatIntervalDay(rs.getInt("repeat_interval_day"));
				ai.setRepeatIntervalHour(rs.getInt("repeat_interval_hour"));
			}

		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("getActivityInfoByKey throw error!");
		} finally {
			DBUtils.close(rs, ps, conn);
		}
		return ai;
	}

	public List getChildren(String paraId) throws DaoException {
		StringBuffer sql = new StringBuffer();
		sql
				.append(
						"select p.id,p.proc_id,p.para_id,p.item_id,p.act_type,p.fillType_Or_appType,p.act_name,")
				.append(
						"p.time_limit,p.appRole_Or_urgDate,p.examRol_Or_colRol,p.description,p.act_state,p.exa_Or_col_type,")
				.append(
						"p.iupdata,u.urge_time,u.urge_info,u.remind_info,u.repeat_count,u.repeat_interval_day,u.repeat_interval_hour ")
				.append(
						" from dc_proc_instance p left join dc_urgency u on p.id=u.act_id where p.para_id = ?");
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;

		List children = null;
		try {
			conn = this.getConnection();
			ps = conn.prepareStatement(sql.toString());
			ps.setString(1, paraId);
			rs = ps.executeQuery();
			children = new ArrayList();
			while (rs.next()) {
				ActivityInstance ai = new ActivityInstance();
				ai.setParaId(rs.getString("para_id"));
				ai.setActivityId(rs.getString("id"));
				ai.setProcId(rs.getString("proc_id"));
				ai.setActivityType(rs.getInt("act_type"));
				ai.setFillTypeOrapproveType(rs.getInt("fillType_Or_appType"));
				ai.setActivityName(rs.getString("act_name"));
				ai.setTimeLimit(rs.getString("time_limit"));
				ai.setApproveUserOrurgencyDate(rs
						.getString("appRole_Or_urgDate"));
				ai.setExamineUserOrcollectionUser(rs
						.getString("examRol_Or_colRol"));
				ai.setDescription(rs.getString("description"));
				ai.setActState(rs.getInt("act_state"));
				ai.setExamineUserOrcollectionUserTypes(rs
						.getString("exa_Or_col_type"));
				ai.setIupdata(rs.getInt("iupdata"));
				ai.setUrgencyContent(rs.getString("urge_info"));
				ai.setRemindContent(rs.getString("remind_info"));
				ai.setUrgencyDate(rs.getString("urge_time"));
				ai.setRepeatCount(rs.getInt("repeat_count"));
				ai.setRepeatIntervalDay(rs.getInt("repeat_interval_day"));
				ai.setRepeatIntervalHour(rs.getInt("repeat_interval_hour"));

				children.add(ai);
			}
		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("getActivityInfoByKey throw error!");
		} finally {
			DBUtils.close(rs, ps, conn);
		}
		return children;
	}

	// public List getNextActivity(String currentActivityId) throws DaoException
	// {
	// List activities = null;
	// QueryOperator query = new QueryOperator();
	// StringBuffer sql = new StringBuffer();
	// sql
	// .append(
	// " select parent.id parentId,parent.act_name parentActName,parent.act_type
	// parentActType,nextParant.id nextParantId,nextParant.act_type
	// nextParantActType,")
	// .append(
	// " nextParant.act_name nextParantActName from dc_proc_instance
	// c,dc_proc_instance parent,dc_proc_instance nextParant where c.para_id =
	// parent.id ")
	// .append(" and parent.para_id = nextParant.id and c.id = ?");
	// try {
	// activities = new ArrayList();
	// query.setSql(sql.toString());
	// query.addParameter(new SqlParameter(SqlType.VARCHAR,
	// currentActivityId));
	// query.access();
	//
	// if (query.resultSetAvailable()) {
	// // 获取并处理记录集
	// RsDataSet rs = new RsDataSet(query.getSqlResultSet());
	//
	// if (rs.rowCount > 0) {
	// ActivityInfo parantActivity = new ActivityInfo();
	// parantActivity.setActivityId(rs
	// .getFieldValueAsString("parentId"));
	// parantActivity.setActivityName(rs
	// .getFieldValueAsString("parentActName"));
	// int parentActType = rs
	// .getFieldValueAsInteger("parentActType") == null ? 0
	// : rs.getFieldValueAsInteger("parentActType")
	// .intValue();
	//
	// ActivityInfo nextParantActivity = new ActivityInfo();
	// nextParantActivity.setActivityId(rs
	// .getFieldValueAsString("nextParantId"));
	// nextParantActivity.setActivityName(rs
	// .getFieldValueAsString("nextParantActName"));
	// int nextParantActType = rs
	// .getFieldValueAsInteger("nextParantActType") == null ? 0
	// : rs.getFieldValueAsInteger("nextParantActType")
	// .intValue();
	//
	// if (parentActType != 0) {
	// activities.add(parantActivity);
	// }
	// if (nextParantActType != 0) {
	// activities.add(nextParantActivity);
	// }
	// }
	//
	// rs.clearAll();
	// }
	// } catch (Exception e) {
	// logger.error("", e);
	// throw new DaoException("getNextActivity throw error!");
	// }
	// return activities;
	// }

	public List getNextActivity(String currentActivityId) throws DaoException {
		List activities = null;
		Connection conn = null;
		try {
			conn = this.getConnection();
			activities = new ArrayList();

			activities = this.getApproveActivity(currentActivityId, conn,
					activities);
		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("getNextActivity throw error!");
		}
		return activities;
	}

	public List getApproveActivity(String currentActivityId, Connection conn,
			List activities) throws DaoException {

		QueryOperator query = new QueryOperator();
		query.setPresentConnection(conn);
		query.setUseOnlyConnectionFlag(true);
		StringBuffer sql = new StringBuffer();
		sql
				.append(
						" select parent.id parentId,parent.act_name parentActName,parent.act_type parentActType ")
				.append(
						" from dc_proc_instance c,dc_proc_instance parent where c.para_id = parent.id and c.id = ?");
		try {
			query.setSql(sql.toString());
			query.addParameter(new SqlParameter(SqlType.VARCHAR,
					currentActivityId));

			query.access();

			if (query.resultSetAvailable()) {
				// 获取并处理记录集
				RsDataSet rs = new RsDataSet(query.getSqlResultSet());

				if (rs.rowCount > 0) {
					ActivityInfo parantActivity = new ActivityInfo();
					parantActivity.setActivityId(rs
							.getFieldValueAsString("parentId"));
					parantActivity.setActivityName(rs
							.getFieldValueAsString("parentActName"));
					int parentActType = rs
							.getFieldValueAsInteger("parentActType") == null ? 0
							: rs.getFieldValueAsInteger("parentActType")
									.intValue();

					if (parentActType != 0) {
						activities.add(parantActivity);
					}
					activities = this.getApproveActivity(parantActivity
							.getActivityId(), conn, activities);
				}

				rs.clearAll();
			}
		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("getNextActivity throw error!");
		}
		return activities;
	}

	public ApproveActivityInstance getApproveActivityInstance(String activityId)
			throws DaoException {

		StringBuffer sql = new StringBuffer();
		sql
				.append(
						"select id,item_id,act_type,filltype_or_apptype,act_name,")
				.append(
						"time_limit,approle_or_urgdate,examrol_or_colrol,description,")
				.append(
						"act_state,iupdata,urgency_content from dc_proc_instance where id=?");

		QueryOperator query = new QueryOperator();
		query.setSql(sql.toString());
		query.addParameter(new SqlParameter(SqlType.VARCHAR, activityId));
		ApproveActivityInstance aai = null;
		try {
			query.access();
			aai = new ApproveActivityInstance();
			if (query.resultSetAvailable()) {
				// 获取并处理记录集
				RsDataSet rs = new RsDataSet(query.getSqlResultSet());

				if (rs.rowCount > 0) {
					int i = 0;
					aai.setActivityId(rs.getFieldValueAsString(i++));
					aai.setProcId(rs.getFieldValueAsString(i++));
					Integer type = rs.getFieldValueAsInteger(i++);
					int typeInt = type == null ? 0 : type.intValue();
					aai.setActivityType(typeInt);

					Integer foType = rs.getFieldValueAsInteger(i++);
					int foTypeInt = foType == null ? 0 : foType.intValue();
					aai.setFillTypeOrapproveType(foTypeInt);
					aai.setActivityName(rs.getFieldValueAsString(i++));
					aai.setTimeLimit(rs.getFieldValueAsString(i++));
					aai.setApproveUserOrurgencyDate(rs
							.getFieldValueAsString(i++));
					aai.setExamineUserOrcollectionUser(rs
							.getFieldValueAsString(i++));
					aai.setDescription(rs.getFieldValueAsString(i++));

					Integer a = rs.getFieldValueAsInteger(i++);
					int aInt = a == null ? 0 : a.intValue();
					aai.setActState(aInt);
					aai.setIupdata(rs.getFieldValueAsInteger(i++).intValue());
					aai.setUrgencyContent(rs
							.getFieldValueAsString("urgency_content"));
					// aai.setRepeatCount(rs.getFieldValueAsInteger("repeat_count").intValue());
					// aai.setRepeatIntervalDay(rs.getFieldValueAsInteger("repeat_interval_day").intValue());
					// aai.setRepeatIntervalHour(rs.getFieldValueAsInteger("repeat_interval_hour").intValue());

				}

				rs.clearAll();
			}

		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("查找编码为：" + activityId + "的审批节点失败！");
		}
		return aai;
	}

	public boolean reconfigActivityPosition(String newParentId,
			String activityId) throws DaoException {
		String sql = "update dc_proc_instance set para_id=? where id = ?";
		UpdateOperator update = new UpdateOperator();
		update.setSql(sql);
		update.addParameter(new SqlParameter(SqlType.VARCHAR, newParentId));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, activityId));

		try {
			update.access();
		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("更新id为：" + activityId + " 的环节的位置失败！");
		}

		int effectCount = update.getEffectCounts();
		if (effectCount > 0) {
			return true;
		} else {
			return false;
		}
	}

	public boolean dynamicAddApproveUsers(String actId, String approveUsers)
			throws DaoException {
		ApproveActivityInstance activity = this.getApproveActivityInstance(actId);
		String sql = "update dc_proc_instance set approle_or_urgdate=? where id = ?";
		UpdateOperator update = new UpdateOperator();
		update.setSql(sql);
		
		String oldApproveUsers = activity.getApproveUserOrurgencyDate();
		String newApproveUsers = "";
		if(StringUtils.isEmpty(oldApproveUsers)){
			newApproveUsers = approveUsers;
		}else{
			newApproveUsers = oldApproveUsers+","+approveUsers;
		}
		
		update.addParameter(new SqlParameter(SqlType.VARCHAR, newApproveUsers));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, actId));

		try {
			update.access();
		} catch (Exception e) {
			logger.error("", e);
			throw new DaoException("动态添加id为：" + actId + " 的环节的审批人失败！");
		}

		int effectCount = update.getEffectCounts();
		if (effectCount > 0) {
			return true;
		} else {
			return false;
		}
	}

}
